"use client"; import { useState, useEffect, useTransition } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Skeleton } from "@/components/ui/skeleton"; import { InfoIcon } from "lucide-react"; import { SwpTable } from "@/lib/swp/table/swp-table"; import { SwpTableToolbar } from "@/lib/swp/table/swp-table-toolbar"; import { fetchSwpDocuments, fetchProjectList, fetchSwpStats, type SwpTableFilters, type SwpDocumentWithStats, } from "@/lib/swp/actions"; interface SwpDocumentPageProps { searchParams: { [key: string]: string | string[] | undefined }; } export default function SwpDocumentPage({ searchParams }: SwpDocumentPageProps) { const router = useRouter(); const params = useSearchParams(); const [isPending, startTransition] = useTransition(); // URL에서 필터 파라미터 추출 const initialFilters: SwpTableFilters = { projNo: (searchParams.projNo as string) || "", docNo: (searchParams.docNo as string) || "", docTitle: (searchParams.docTitle as string) || "", pkgNo: (searchParams.pkgNo as string) || "", vndrCd: (searchParams.vndrCd as string) || "", stage: (searchParams.stage as string) || "", }; const initialPage = parseInt((searchParams.page as string) || "1", 10); const initialPageSize = parseInt((searchParams.pageSize as string) || "100", 10); // 상태 관리 const [documents, setDocuments] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(initialPage); const [pageSize] = useState(initialPageSize); const [totalPages, setTotalPages] = useState(0); const [filters, setFilters] = useState(initialFilters); const [projects, setProjects] = useState>([]); const [stats, setStats] = useState({ total_documents: 0, total_revisions: 0, total_files: 0, last_sync: null as Date | null, }); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // 초기 데이터 로드 useEffect(() => { loadInitialData(); }, []); // 필터 변경 시 데이터 재로드 useEffect(() => { if (!isLoading) { loadDocuments(); } }, [filters, page]); const loadInitialData = async () => { try { setIsLoading(true); setError(null); // 병렬로 데이터 로드 const [projectsData, statsData, documentsData] = await Promise.all([ fetchProjectList(), fetchSwpStats(), fetchSwpDocuments({ page, pageSize, filters: Object.keys(initialFilters).length > 0 ? initialFilters : undefined, }), ]); setProjects(projectsData); setStats(statsData); setDocuments(documentsData.data); setTotal(documentsData.total); setTotalPages(documentsData.totalPages); } catch (err) { console.error("초기 데이터 로드 실패:", err); setError(err instanceof Error ? err.message : "데이터 로드 실패"); } finally { setIsLoading(false); } }; const loadDocuments = async () => { startTransition(async () => { try { const data = await fetchSwpDocuments({ page, pageSize, filters: Object.keys(filters).some((key) => filters[key as keyof SwpTableFilters]) ? filters : undefined, }); setDocuments(data.data); setTotal(data.total); setTotalPages(data.totalPages); // URL 업데이트 const params = new URLSearchParams(); if (filters.projNo) params.set("projNo", filters.projNo); if (filters.docNo) params.set("docNo", filters.docNo); if (filters.docTitle) params.set("docTitle", filters.docTitle); if (filters.pkgNo) params.set("pkgNo", filters.pkgNo); if (filters.vndrCd) params.set("vndrCd", filters.vndrCd); if (filters.stage) params.set("stage", filters.stage); if (page !== 1) params.set("page", page.toString()); router.push(`?${params.toString()}`, { scroll: false }); } catch (err) { console.error("문서 로드 실패:", err); setError(err instanceof Error ? err.message : "문서 로드 실패"); } }); }; const handleFiltersChange = (newFilters: SwpTableFilters) => { setFilters(newFilters); setPage(1); // 필터 변경 시 첫 페이지로 }; const handlePageChange = (newPage: number) => { setPage(newPage); }; if (isLoading) { return ( ); } if (error) { return ( {error} ); } return (
{/* 통계 카드 */}
총 문서 {stats.total_documents.toLocaleString()} 총 리비전 {stats.total_revisions.toLocaleString()} 총 파일 {stats.total_files.toLocaleString()} 마지막 동기화 {stats.last_sync ? new Date(stats.last_sync).toLocaleDateString("ko-KR") : "없음"}
{/* 안내 메시지 */} {documents.length === 0 && !filters.projNo && ( 시작하려면 프로젝트를 선택하고 SWP 동기화 버튼을 클릭하세요. )} {/* 메인 테이블 */}
); }